package com.gitee.hermer.engine.jars.app.sdk.configuration;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import com.gitee.hermer.boot.jee.commons.bean.utils.BeanLocator;
import com.gitee.hermer.boot.jee.commons.collection.StringCache;
import com.gitee.hermer.boot.jee.commons.log.UtilsContext;
import com.gitee.hermer.engine.jars.app.sdk.EngineAppClassLoader;
import com.gitee.hermer.engine.jars.core.autoconfigure.annotate.ConditionalOnBean;
import com.gitee.hermer.engine.jars.core.autoconfigure.annotate.ConditionalOnEngineApplication;
import com.gitee.hermer.engine.jars.core.autoconfigure.annotate.ConditionalOnEngineBean;
import com.gitee.hermer.engine.jars.core.domain.EngineConstant;
import com.gitee.hermer.engine.jars.dependent.zipkin.EngineZipkinConfig;

import brave.Tracing;
import brave.context.slf4j.MDCCurrentTraceContext;
import brave.http.HttpTracing;
import brave.propagation.B3Propagation;
import brave.propagation.ExtraFieldPropagation;
import zipkin2.reporter.Reporter;

@Configuration
@ConditionalOnEngineApplication
@ConditionalOnEngineBean(name=EngineConstant.SPRING_BEAN_NAME_ZIPKIN_CONFIG)
public class EngineAppZipkinAutoConfiguration extends UtilsContext implements Ordered,ApplicationContextAware{

	private ApplicationContext applicationContext;

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		this.applicationContext = applicationContext;
	}

	@Bean EngineZipkinConfig engineZipkinConfig(){
		try{
			EngineAppClassLoader classLoader = (EngineAppClassLoader) Thread.currentThread().getContextClassLoader();
			EngineZipkinConfig config = (EngineZipkinConfig) BeanLocator.getBean(EngineZipkinConfig.class).clone();
			config.setAppName(classLoader.appName());
			config.setAppVersion(classLoader.appVersion());
			return config;
		}catch (Exception e) {
			throw new IllegalStateException(e.getMessage(),e);
		}
	}

//	@Bean(name={EngineConstant.SPRING_BEAN_NAME_ZIPKIN_SENDER_BEAN})
//	public Sender sender(EngineZipkinConfig config)
//	{
//		try{
//			return BeanLocator.getBean(Sender.class);
//		}catch (Exception e) {
//			throw new IllegalStateException(e.getMessage(), e);
//		}
//	}
//
//	@Bean Reporter<Span> asyncReporterFactoryBean(Sender sender,EngineZipkinConfig config) throws Exception{
//		//		return AsyncReporter.builder(sender)
//		//				.closeTimeout(config.getClientTimeout(), TimeUnit.MILLISECONDS).build(SpanBytesEncoder.JSON_V2);
//		try{
//			return BeanLocator.getBean(Reporter.class);
//		}catch (Exception e) {
//			throw new IllegalStateException(e.getMessage(), e);
//		} 
//	}



	@Bean(EngineConstant.SPRING_BEAN_NAME_ZIPKIN_TRACING_BEAN)
	public Tracing tracingFactoryBean(EngineZipkinConfig config) throws Exception{
		return Tracing.newBuilder().localServiceName(new StringCache(config.getAppName()).append(EngineConstant.STR_SPLIT).append(config.getAppVersion()).toString())
				.propagationFactory(ExtraFieldPropagation.newFactory(B3Propagation.FACTORY, "user-name"))
				.currentTraceContext(MDCCurrentTraceContext.create()).spanReporter(BeanLocator.getBean(Reporter.class)).build();
	}

	@Bean HttpTracing httpTracingFactoryBean(Tracing tracing) throws Exception{
		return HttpTracing.create(tracing);
	}

	@Override
	public int getOrder() {
		return 0;
	}



}
